---
sidebar_label: Role based column presets
sidebar_position: 3
description: Set field values for Postgres using role-based column presets
keywords:
  - hasura
  - docs
  - postgres
  - schema
  - role-based
  - column preset
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Thumbnail from '@site/src/components/Thumbnail';

# Postgres: Setting Values for Fields Using Role-Based Column Presets

## Introduction

Let's say you want certain fields to have their values set automatically using session variables or fixed values when a
row is created/updated with a particular [user role](/auth/authorization/roles-variables.mdx).

Hasura GraphQL Engine's column presets let you define role-based values for any field/column. These values can either be
a session variable value or a static value.

:::caution Column preset restricts mutation access for configured role

Column preset values are not overridable by the user. ie. If a column has a preset defined for a given role, access to
the column for the mutation will be restricted for users with that role.

:::

**Example:** Say we have a field `user_id` in a table `article` which is to be set to the id of the user, from the value
of the user's session variable whenever a new row is added to the `article` table.

## Step 1: Configure a column preset

<Tabs groupId="user-preference" className="api-tabs">
<TabItem value="console" label="Console">

The column preset option is available under the `Permissions` tab of a table. Open the Console and head to
`Data -> [article] -> Permissions`:

<Thumbnail src="/img/schema/column-presets-option.png" alt="Add a column preset in the permissions tab" />

Enable the column preset option to define presets for one or more columns. For each column, you can pick between setting
the preset using a static value or from a session variable.

<Thumbnail src="/img/schema/column-presets-value-options.png" alt="Configure the column preset" />

For our chosen example, we'll use the `from session variable` option and configure the `user_id` column to be
automatically populated based on the value of the `X-Hasura-User-Id` session variable.

</TabItem>
<TabItem value="cli" label="CLI">

You can set column presets in the `tables.yaml` file inside the `metadata` directory:

```yaml {8-9}
- table:
    schema: public
    name: article
  insert_permissions:
    - role: user
      permission:
        check: {}
        set:
          user_id: x-hasura-User-Id
        columns:
          - content
          - rating
          - title
        backend_only: false
```

Apply the Metadata by running:

```bash
hasura metadata apply
```

</TabItem>
<TabItem value="api" label="API">

You can add column presets by using the
[pg_create_insert_permission](/api-reference/metadata-api/permission.mdx#metadata-pg-create-insert-permission) metadata
API:

```http {13-15}
POST /v1/metadata HTTP/1.1
Content-Type: application/json
X-Hasura-Role: admin

{
  "type" : "pg_create_insert_permission",
  "args" : {
    "source": "<db_name>",
    "table" : "article",
    "role" : "user",
    "permission" : {
      "check" : {},
      "set":{
        "user_id":"X-Hasura-User-Id"
      },
      "columns":["title", "content", "rating"]
    }
  }
}
```

</TabItem>
</Tabs>

:::info Note

To set a column preset for a nested object's column, simply set the corresponding column preset in the remote table.

:::

## Step 2: Run an insert mutation

Head to the GraphiQL interface in the Console and try making an insert mutation on the `article` table with the
following headers (_to run through this example, don't forget to also grant the_ `user` _role sufficient permissions to
select from the_ `article` _table_):

- `X-Hasura-Role` --> `user` (_to test the behavior for the configured role_)
- `X-Hasura-User-Id` --> `1` (_this is the value we should expect in the_ `user_id` _field_)

As mentioned earlier, you'll notice when you add the `X-Hasura-Role` header that the field, `user_id`, is no longer
available as the mutation type's field:

<Thumbnail src="/img/schema/column-preset-schema-change-for-role.png" alt="Write an insert mutation" />

Now, if we run the following insert mutation, we'll see that the `user_id` field is indeed being set with the value
passed in the `X-Hasura-User-Id` variable:

<Thumbnail src="/img/schema/column-preset-mutation-result.png" alt="Write an insert mutation" />

:::info Note

Not passing the configured header will result in a run-time error:

```json
{
  "errors": [
    {
      "path": "$",
      "error": "\"x-hasura-user-id\" header is expected but not found",
      "code": "not-found"
    }
  ]
}
```

:::

## Also see

- [Postgres: Setting default values for fields using Postgres defaults](/schema/postgres/default-values/postgres-defaults.mdx)
- [Postgres: Setting values of fields using SQL functions](/schema/postgres/default-values/sql-functions.mdx)
